home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Gfx / Edit / TSMorph / src / SaveHAMetc.c < prev    next >
C/C++ Source or Header  |  1994-10-31  |  16KB  |  840 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. // This is routines to save chunky 24 bit RGB in various formats
  21. // B&W 16 grey scale
  22. // B&W 256 grey scale
  23. // HAM6 with fixed palette (but could easily used variable palette)
  24. // HAM6 with fixed palette (but could easily used variable palette)
  25. // DCTV
  26.  
  27. // include headers
  28. #include <proto/iffparse.h>
  29. #include <graphics/view.h>
  30. #include <libraries/dctv.h>
  31. #include <clib/dctv_protos.h>
  32. #include <pragmas/dctv_pragmas.h>
  33. extern struct Library *DCTVBase;
  34.  
  35. // IFF header
  36. #include "iffp/ILBMapp.h"
  37.  
  38. // Following explains(?) the palette choices
  39.  
  40. //   0 = x00 = b00000000
  41. //  85 = x55 = b01010101
  42. // 170 = xaa = b10101010
  43. // 255 = xff = b11111111
  44.  
  45. //   0 = x00 = o000 = b00000000
  46. //  36 = x24 = o111 = b00100100
  47. //  73 = x49 = o222 = b01001001
  48. // 109 = x6d = o333 = b01101101
  49. // 146 = x92 = o444 = b10010010
  50. // 182 = xb6 = o555 = b10110110
  51. // 219 = xdb = o666 = b11011011
  52. // 255 = xff = o777 = b11111111
  53.  
  54. //   0 = x00 = b00000000
  55. //  17 = x11 = b00010001
  56. //  34 = x22 = b00100010
  57. //  51 = x33 = b00110011
  58. //  68 = x44 = b01000100
  59. //  85 = x55 = b01010101
  60. // 102 = x66 = b01100110
  61. // 119 = x77 = b01110111
  62. // 136 = x88 = b10001000
  63. // 153 = x99 = b10011001
  64. // 170 = xaa = b10101010
  65. // 187 = xbb = b10111011
  66. // 204 = xcc = b11001100
  67. // 221 = xdd = b11011101
  68. // 238 = xee = b11101110
  69. // 255 = xff = b11111111 
  70.  
  71. // 16 grey shade palette
  72. UBYTE BW16_Palette[48] = {
  73.     0,0,0,
  74.     17,17,17,
  75.     34,34,34,
  76.     51,51,51,
  77.     68,68,68,
  78.     85,85,85,
  79.     102,102,102,
  80.     119,119,119,
  81.     136,136,136,
  82.     153,153,153,
  83.     170,170,170,
  84.     187,187,187,
  85.     204,204,204,
  86.     221,221,221,
  87.     238,238,238,
  88.     255,255,255
  89. };
  90.  
  91. // 256 grey shade palette
  92. UBYTE BW256_Palette[768] = {
  93.     0,0,0,
  94.     1,1,1,
  95.     2,2,2,
  96.     3,3,3,
  97.     4,4,4,
  98.     5,5,5,
  99.     6,6,6,
  100.     7,7,7,
  101.     8,8,8,
  102.     9,9,9,
  103.     10,10,10,
  104.     11,11,11,
  105.     12,12,12,
  106.     13,13,13,
  107.     14,14,14,
  108.     15,15,15,
  109.     16,16,16,
  110.     17,17,17,
  111.     18,18,18,
  112.     19,19,19,
  113.     20,20,20,
  114.     21,21,21,
  115.     22,22,22,
  116.     23,23,23,
  117.     24,24,24,
  118.     25,25,25,
  119.     26,26,26,
  120.     27,27,27,
  121.     28,28,28,
  122.     29,29,29,
  123.     30,30,30,
  124.     31,31,31,
  125.     32,32,32,
  126.     33,33,33,
  127.     34,34,34,
  128.     35,35,35,
  129.     36,36,36,
  130.     37,37,37,
  131.     38,38,38,
  132.     39,39,39,
  133.     40,40,40,
  134.     41,41,41,
  135.     42,42,42,
  136.     43,43,43,
  137.     44,44,44,
  138.     45,45,45,
  139.     46,46,46,
  140.     47,47,47,
  141.     48,48,48,
  142.     49,49,49,
  143.     50,50,50,
  144.     51,51,51,
  145.     52,52,52,
  146.     53,53,53,
  147.     54,54,54,
  148.     55,55,55,
  149.     56,56,56,
  150.     57,57,57,
  151.     58,58,58,
  152.     59,59,59,
  153.     60,60,60,
  154.     61,61,61,
  155.     62,62,62,
  156.     63,63,63,
  157.     64,64,64,
  158.     65,65,65,
  159.     66,66,66,
  160.     67,67,67,
  161.     68,68,68,
  162.     69,69,69,
  163.     70,70,70,
  164.     71,71,71,
  165.     72,72,72,
  166.     73,73,73,
  167.     74,74,74,
  168.     75,75,75,
  169.     76,76,76,
  170.     77,77,77,
  171.     78,78,78,
  172.     79,79,79,
  173.     80,80,80,
  174.     81,81,81,
  175.     82,82,82,
  176.     83,83,83,
  177.     84,84,84,
  178.     85,85,85,
  179.     86,86,86,
  180.     87,87,87,
  181.     88,88,88,
  182.     89,89,89,
  183.     90,90,90,
  184.     91,91,91,
  185.     92,92,92,
  186.     93,93,93,
  187.     94,94,94,
  188.     95,95,95,
  189.     96,96,96,
  190.     97,97,97,
  191.     98,98,98,
  192.     99,99,99,
  193.     100,100,100,
  194.     101,101,101,
  195.     102,102,102,
  196.     103,103,103,
  197.     104,104,104,
  198.     105,105,105,
  199.     106,106,106,
  200.     107,107,107,
  201.     108,108,108,
  202.     109,109,109,
  203.     110,110,110,
  204.     111,111,111,
  205.     112,112,112,
  206.     113,113,113,
  207.     114,114,114,
  208.     115,115,115,
  209.     116,116,116,
  210.     117,117,117,
  211.     118,118,118,
  212.     119,119,119,
  213.     120,120,120,
  214.     121,121,121,
  215.     122,122,122,
  216.     123,123,123,
  217.     124,124,124,
  218.     125,125,125,
  219.     126,126,126,
  220.     127,127,127,
  221.     128,128,128,
  222.     129,129,129,
  223.     130,130,130,
  224.     131,131,131,
  225.     132,132,132,
  226.     133,133,133,
  227.     134,134,134,
  228.     135,135,135,
  229.     136,136,136,
  230.     137,137,137,
  231.     138,138,138,
  232.     139,139,139,
  233.     140,140,140,
  234.     141,141,141,
  235.     142,142,142,
  236.     143,143,143,
  237.     144,144,144,
  238.     145,145,145,
  239.     146,146,146,
  240.     147,147,147,
  241.     148,148,148,
  242.     149,149,149,
  243.     150,150,150,
  244.     151,151,151,
  245.     152,152,152,
  246.     153,153,153,
  247.     154,154,154,
  248.     155,155,155,
  249.     156,156,156,
  250.     157,157,157,
  251.     158,158,158,
  252.     159,159,159,
  253.     160,160,160,
  254.     161,161,161,
  255.     162,162,162,
  256.     163,163,163,
  257.     164,164,164,
  258.     165,165,165,
  259.     166,166,166,
  260.     167,167,167,
  261.     168,168,168,
  262.     169,169,169,
  263.     170,170,170,
  264.     171,171,171,
  265.     172,172,172,
  266.     173,173,173,
  267.     174,174,174,
  268.     175,175,175,
  269.     176,176,176,
  270.     177,177,177,
  271.     178,178,178,
  272.     179,179,179,
  273.     180,180,180,
  274.     181,181,181,
  275.     182,182,182,
  276.     183,183,183,
  277.     184,184,184,
  278.     185,185,185,
  279.     186,186,186,
  280.     187,187,187,
  281.     188,188,188,
  282.     189,189,189,
  283.     190,190,190,
  284.     191,191,191,
  285.     192,192,192,
  286.     193,193,193,
  287.     194,194,194,
  288.     195,195,195,
  289.     196,196,196,
  290.     197,197,197,
  291.     198,198,198,
  292.     199,199,199,
  293.     200,200,200,
  294.     201,201,201,
  295.     202,202,202,
  296.     203,203,203,
  297.     204,204,204,
  298.     205,205,205,
  299.     206,206,206,
  300.     207,207,207,
  301.     208,208,208,
  302.     209,209,209,
  303.     210,210,210,
  304.     211,211,211,
  305.     212,212,212,
  306.     213,213,213,
  307.     214,214,214,
  308.     215,215,215,
  309.     216,216,216,
  310.     217,217,217,
  311.     218,218,218,
  312.     219,219,219,
  313.     220,220,220,
  314.     221,221,221,
  315.     222,222,222,
  316.     223,223,223,
  317.     224,224,224,
  318.     225,225,225,
  319.     226,226,226,
  320.     227,227,227,
  321.     228,228,228,
  322.     229,229,229,
  323.     230,230,230,
  324.     231,231,231,
  325.     232,232,232,
  326.     233,233,233,
  327.     234,234,234,
  328.     235,235,235,
  329.     236,236,236,
  330.     237,237,237,
  331.     238,238,238,
  332.     239,239,239,
  333.     240,240,240,
  334.     241,241,241,
  335.     242,242,242,
  336.     243,243,243,
  337.     244,244,244,
  338.     245,245,245,
  339.     246,246,246,
  340.     247,247,247,
  341.     248,248,248,
  342.     249,249,249,
  343.     250,250,250,
  344.     251,251,251,
  345.     252,252,252,
  346.     253,253,253,
  347.     254,254,254,
  348.     255,255,255,
  349. };
  350.  
  351. // HAM6 base palette
  352. // note 3 extra entries based on changing r,g or b using HAM stuff
  353. UBYTE HAM6_Palette[57] = {
  354.     0,0,0,
  355.     0,0,170,
  356.     0,85,0,
  357.     0,85,170,
  358.     0,170,0,
  359.     0,170,170,
  360.     0,255,0,
  361.     0,255,170,
  362.     170,0,0,
  363.     170,0,170,
  364.     170,85,0,
  365.     170,85,170,
  366.     170,170,0,
  367.     170,170,170,
  368.     170,255,0,
  369.     170,255,170,
  370.     0,0,0,    // r
  371.     0,0,0,    // g
  372.     0,0,0,    // b
  373. };
  374.  
  375. // HAM8 base palette
  376. // note 3 extra entries based on changing r,g or b using HAM stuff
  377. UBYTE HAM8_Palette[201] = {
  378.     0,0,0,
  379.     0,0,170,
  380.     0,36,0,
  381.     0,36,170,
  382.     0,73,0,
  383.     0,73,170,
  384.     0,109,0,
  385.     0,109,170,
  386.     0,146,0,
  387.     0,146,170,
  388.     0,182,0,
  389.     0,182,170,
  390.     0,219,0,
  391.     0,219,170,
  392.     0,255,0,
  393.     0,255,170,
  394.     85,0,0,
  395.     85,0,170,
  396.     85,36,0,
  397.     85,36,170,
  398.     85,73,0,
  399.     85,73,170,
  400.     85,109,0,
  401.     85,109,170,
  402.     85,146,0,
  403.     85,146,170,
  404.     85,182,0,
  405.     85,182,170,
  406.     85,219,0,
  407.     85,219,170,
  408.     85,255,0,
  409.     85,255,170,
  410.     170,0,0,
  411.     170,0,170,
  412.     170,36,0,
  413.     170,36,170,
  414.     170,73,0,
  415.     170,73,170,
  416.     170,109,0,
  417.     170,109,170,
  418.     170,146,0,
  419.     170,146,170,
  420.     170,182,0,
  421.     170,182,170,
  422.     170,219,0,
  423.     170,219,170,
  424.     170,255,0,
  425.     170,255,170,
  426.     255,0,0,
  427.     255,0,170,
  428.     255,36,0,
  429.     255,36,170,
  430.     255,73,0,
  431.     255,73,170,
  432.     255,109,0,
  433.     255,109,170,
  434.     255,146,0,
  435.     255,146,170,
  436.     255,182,0,
  437.     255,182,170,
  438.     255,219,0,
  439.     255,219,170,
  440.     255,255,0,
  441.     255,255,170,
  442.     0,0,0,    // r
  443.     0,0,0,    // g
  444.     0,0,0,    // b
  445. };
  446.  
  447. /* save 16 grey scale
  448.  * FileName : file to save
  449.  * width    : width of image
  450.  * height   : height of image
  451.  * swidth   : widht of image when in full words
  452.  * pwidth   : page width
  453.  * pheight  : page height
  454.  * pmode    : camg chunk
  455.  * red      : red
  456.  * green    : green
  457.  * blue     : blue chunky bit map
  458.  * rp       : a work rast port
  459.  * trp      : another work rast port
  460.  */
  461. BOOL
  462. SaveBW16(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  463.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  464.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  465.     UBYTE *r,*g,*b,*old;
  466.     UWORD x,y;
  467.     BOOL OkFlag;
  468.     struct ILBMInfo *ilbm;
  469.     // allocate IFF stuff
  470.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  471.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  472.             r = red;
  473.             g = green;
  474.             b = blue;
  475.             old = red;
  476.             // for each line
  477.             for (y=0;
  478.                   y<height;
  479.                   y++) {
  480.                 // for each column
  481.                 for (x=0;
  482.                       x < width;
  483.                       x++) {
  484.                     // convert rgb to 16 grey scale
  485.                     *old++ = ((30 * *r++) + (59 * *g++) + (11 * *b++)) / 1594;
  486.                 }
  487.                 r += (swidth - width);
  488.                 g += (swidth - width);
  489.                 b += (swidth - width);
  490.                 old += (swidth - width);
  491.             }
  492.             // convert chunky to planar
  493.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  494.             // and save IFF
  495.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode,
  496.                                      width,  height, pwidth, pheight,
  497.                                      BW16_Palette, 16, 8,    /* colortable */
  498.                                      mskNone, 0,    /* masking, transparent */
  499.                                      NULL, NULL,     /* chunklists */
  500.                                      FileName);
  501.             // Close everything down cleanly
  502.             FreeIFF(ilbm->ParseInfo.iff);
  503.         }
  504.         else {
  505.             OkFlag = FALSE;
  506.         }
  507.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  508.     }
  509.     else {
  510.         OkFlag = FALSE;
  511.     }
  512.     return OkFlag;
  513. }
  514.  
  515. /* save 256 grey scale
  516.  * see SaveBW16()
  517.  */
  518. BOOL
  519. SaveBW256(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  520.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  521.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  522.     UBYTE *r,*g,*b,*old;
  523.     UWORD x,y;
  524.     BOOL OkFlag;
  525.     struct ILBMInfo *ilbm;
  526.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  527.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  528.             r = red;
  529.             g = green;
  530.             b = blue;
  531.             old = red;
  532.             for (y=0;
  533.                   y<height;
  534.                   y++) {
  535.                 for (x=0;
  536.                       x < width;
  537.                       x++) {
  538.                     // convert rgb to 256 grey scale
  539.                     *old = ((30 * *r++) + (59 * *g++) + (11 * *b++)) / 100;
  540.                 }
  541.                 r += (swidth - width);
  542.                 g += (swidth - width);
  543.                 b += (swidth - width);
  544.                 old += (swidth - width);
  545.             }
  546.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  547.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode,
  548.                                      width,  height, pwidth, pheight,
  549.                                      BW256_Palette, 256, 8,    /* colortable */
  550.                                      mskNone, 0,    /* masking, transparent */
  551.                                      NULL, NULL,     /* chunklists */
  552.                                      FileName);
  553.             // Close everything down cleanly
  554.             FreeIFF(ilbm->ParseInfo.iff);
  555.         }
  556.         else {
  557.             OkFlag = FALSE;
  558.         }
  559.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  560.     }
  561.     else {
  562.         OkFlag = FALSE;
  563.     }
  564.     return OkFlag;
  565. }
  566.  
  567. /* save HAM6
  568.  * see SaveBW16()
  569.  */
  570. BOOL
  571. SaveHAM6(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  572.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  573.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  574.     UBYTE *r,*g,*b,*old,*p;
  575.     UWORD x,y;
  576.     ULONG maxdiff;
  577.     ULONG diff;
  578.     LONG t;
  579.     UWORD k;
  580.     UWORD index;
  581.     BOOL OkFlag;
  582.     struct ILBMInfo *ilbm;
  583.     UBYTE lr,lg,lb;
  584.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  585.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  586.             r = red;
  587.             g = green;
  588.             b = blue;
  589.             old = red;
  590.             for (y=0;
  591.                   y<height;
  592.                   y++) {
  593.                 lr = 0;
  594.                 lg = 0;
  595.                 lb = 0;
  596.                 for (x=0;
  597.                       x < width;
  598.                       x++) {
  599.                     // colour if we use HAM to change R or G or B
  600.                     HAM6_Palette[16*3] = *r;
  601.                     HAM6_Palette[16*3+1] = lg;
  602.                     HAM6_Palette[16*3+2] = lb;
  603.                     HAM6_Palette[17*3] = lr;
  604.                     HAM6_Palette[17*3+1] = *g;
  605.                     HAM6_Palette[17*3+2] = lb;
  606.                     HAM6_Palette[18*3] = lr;
  607.                     HAM6_Palette[18*3+1] = lg;
  608.                     HAM6_Palette[18*3+2] = *b;
  609.                     // Find closest color
  610.                     maxdiff = 0x7FFFFFFF;
  611.                     p = HAM6_Palette;
  612.                     for (k = 0;
  613.                           k < 19;
  614.                           ++k) {
  615.                         t = *r - *p++;
  616.                         diff = t*t*3;
  617.                         t = *g - *p++;
  618.                         diff += (t*t*6);
  619.                         t = *b - *p++;
  620.                         diff += (t*t);
  621.                         if (diff < maxdiff) {
  622.                             maxdiff = diff;
  623.                             index = k;
  624.                         }
  625.                     }
  626.                     lr = HAM6_Palette[index*3];
  627.                     lg = HAM6_Palette[index*3+1];
  628.                     lb = HAM6_Palette[index*3+2];
  629.                     // Set HAM bits if required
  630.                     if (index == 16) {
  631.                         *old++ = (*r>>4) | 0x20;
  632.                     }
  633.                     else {
  634.                         if (index == 17) {
  635.                             *old++ = (*g>>4) | 0x30;
  636.                         }
  637.                         else {
  638.                             if (index == 18) {
  639.                                 *old++ = (*b>>4) | 0x10;
  640.                             }
  641.                             else {
  642.                                 *old++ = index;
  643.                             }
  644.                         }
  645.                     }
  646.                     r++;
  647.                     g++;
  648.                     b++;
  649.                 }
  650.                 r += (swidth - width);
  651.                 g += (swidth - width);
  652.                 b += (swidth - width);
  653.                 old += (swidth - width);
  654.             }
  655.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  656.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode | HAM,
  657.                                      width,  height, pwidth, pheight,
  658.                                      HAM6_Palette, 16, 8,    /* colortable */
  659.                                      mskNone, 0,    /* masking, transparent */
  660.                                      NULL, NULL,     /* chunklists */
  661.                                      FileName);
  662.             // Close everything down cleanly
  663.             FreeIFF(ilbm->ParseInfo.iff);
  664.         }
  665.         else {
  666.             OkFlag = FALSE;
  667.         }
  668.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  669.     }
  670.     else {
  671.         OkFlag = FALSE;
  672.     }
  673.     return OkFlag;
  674. }
  675.  
  676. /* save HAM8
  677.  * see SaveHAM6()
  678.  */
  679. BOOL SaveHAM8(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  680.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  681.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  682.     UBYTE *r,*g,*b,*old,*p;
  683.     UWORD x,y;
  684.     ULONG maxdiff;
  685.     ULONG diff;
  686.     LONG t;
  687.     UWORD k;
  688.     UWORD index;
  689.     BOOL OkFlag;
  690.     struct ILBMInfo *ilbm;
  691.     UBYTE lr,lg,lb;
  692.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  693.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  694.             r = red;
  695.             g = green;
  696.             b = blue;
  697.             old = red;
  698.             for (y=0;
  699.                   y<height;
  700.                   y++) {
  701.                 lr = 0;
  702.                 lg = 0;
  703.                 lb = 0;
  704.                 for (x=0;
  705.                       x < width;
  706.                       x++) {
  707.                     HAM8_Palette[64*3] = *r;
  708.                     HAM8_Palette[64*3+1] = lg;
  709.                     HAM8_Palette[64*3+2] = lb;
  710.                     HAM8_Palette[65*3] = lr;
  711.                     HAM8_Palette[65*3+1] = *g;
  712.                     HAM8_Palette[65*3+2] = lb;
  713.                     HAM8_Palette[66*3] = lr;
  714.                     HAM8_Palette[66*3+1] = lg;
  715.                     HAM8_Palette[66*3+2] = *b;
  716.                     // Find closest color
  717.                     maxdiff = 0x7FFFFFFF;
  718.                     p = HAM8_Palette;
  719.                     for (k = 0;
  720.                           k < 67;
  721.                           ++k) {
  722.                         t = *r - *p++;
  723.                         diff = t*t*3;
  724.                         t = *g - *p++;
  725.                         diff += (t*t*6);
  726.                         t = *b - *p++;;
  727.                         diff += (t*t);
  728.                         if (diff < maxdiff) {
  729.                             maxdiff = diff;
  730.                             index = k;
  731.                         }
  732.                     }
  733.                     lr = HAM8_Palette[index*3];
  734.                     lg = HAM8_Palette[index*3+1];
  735.                     lb = HAM8_Palette[index*3+2];
  736.                     if (index == 64) {
  737.                         *old++ = (*r>>2) | 0x80;
  738.                     }
  739.                     else {
  740.                         if (index == 65) {
  741.                             *old++ = (*g>>2) | 0xc0;
  742.                         }
  743.                         else {
  744.                             if (index == 66) {
  745.                                 *old++ = (*b>>2) | 0x40;
  746.                             }
  747.                             else {
  748.                                 *old++ = index;
  749.                             }
  750.                         }
  751.                     }
  752.                     r++;
  753.                     g++;
  754.                     b++;
  755.                 }
  756.                 r += (swidth - width);
  757.                 g += (swidth - width);
  758.                 b += (swidth - width);
  759.                 old += (swidth - width);
  760.             }
  761.             WritePixelArray8(rp,0,0,width-1,height-1,red,trp);
  762.             OkFlag = !saveilbm(ilbm, rp->BitMap, pmode | HAM,
  763.                                      width,  height, pwidth, pheight,
  764.                                      HAM8_Palette, 64, 8,    /* colortable */
  765.                                      mskNone, 0,    /* masking, transparent */
  766.                                      NULL, NULL,     /* chunklists */
  767.                                      FileName);
  768.             // Close everything down cleanly
  769.             FreeIFF(ilbm->ParseInfo.iff);
  770.         }
  771.         else {
  772.             OkFlag = FALSE;
  773.         }
  774.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  775.     }
  776.     else {
  777.         OkFlag = FALSE;
  778.     }
  779.     return OkFlag;
  780. }
  781.  
  782. /* save DCTV
  783.  * see SaveBW16()
  784.  */
  785. BOOL SaveDCTV(UBYTE *FileName,USHORT width,USHORT height, UWORD swidth,
  786.                   USHORT pwidth, USHORT pheight, USHORT pmode,
  787.                   UBYTE *red, UBYTE *green, UBYTE *blue, struct RastPort *rp, struct RastPort *trp) {
  788.     UWORD i;
  789.     BOOL OkFlag;
  790.     struct ILBMInfo *ilbm;
  791.     struct DCTVCvtHandle *chandle;
  792.  
  793.     if (ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  794.         if (ilbm->ParseInfo.iff = AllocIFF()) {
  795.             // Allocate DCTV stuff
  796.             if (chandle = AllocDCTVCvtTags(rp->BitMap,
  797.                                             DCTVCVTA_Type, DCTVCVTT_RGBtoDCTV,
  798.                                             DCTVCVTA_Flags,((pmode|LACE)?DCTVCVTF_Lace:0)|
  799.                                                                 DCTVCVTF_Filter|
  800.                                                                 DCTVCVTF_CustomRGBBuf,
  801.                                             TAG_END)) {
  802.                 chandle->Red = red;
  803.                 chandle->Green = green;
  804.                 chandle->Blue = blue;
  805.                 // Convert each line
  806.                 while (chandle->DstLineNum < chandle->Height) {
  807.                     i = chandle->SrcLineNum;
  808.                     CvtDCTVLine(chandle);
  809.                     if (i != chandle->SrcLineNum) {
  810.                         chandle->Red += swidth;
  811.                         chandle->Green += swidth;
  812.                         chandle->Blue += swidth;
  813.                     }
  814.                 }
  815.                 OkFlag = !saveilbm(ilbm, rp->BitMap, pmode,
  816.                                      width,  height, pwidth, pheight,
  817.                                      chandle->ColorTable, 1L << rp->BitMap->Depth, 4,    /* colortable */
  818.                                      mskNone, 0,    /* masking, transparent */
  819.                                      NULL, NULL,     /* chunklists */
  820.                                      FileName);
  821.                 // Free DCTV stuff
  822.                 FreeDCTVCvt(chandle);
  823.             }
  824.             else {
  825.                 OkFlag = FALSE;
  826.             }
  827.             // Close everything down cleanly
  828.             FreeIFF(ilbm->ParseInfo.iff);
  829.         }
  830.         else {
  831.             OkFlag = FALSE;
  832.         }
  833.         FreeMem(ilbm,sizeof(struct ILBMInfo));
  834.     }
  835.     else {
  836.         OkFlag = FALSE;
  837.     }
  838.     return OkFlag;
  839. }
  840.